﻿/* MDA.Net - .Net port of mda-vst plugins
 * 
 * .Net port, Copyright (C) 2011, Balint Pfliegel
 * Based on mda-vst, Copyright (C) 1999-2001 Paul Kellett (maxim digital audio)
 * Based on VST2 SDK (c) 1996-1999 Steinberg Soft und Hardware GmbH, All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA.
 */

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MDA.Net.Effects.Interfaces;
using System.Collections.Generic;

namespace MDA.Net.Effects
{
    public class OverdriveEffect : IEffect
    {
        float[] _params = new float[4];
        double filt1 = 0.0, filt2 = 0.0, filt, gain, mix;

        // Drive, Muffle, Output, Mix
        // 100 * fParam1, 100 * fParam2, 40 * fParam3 - 20, 0-1
        // %,%, dB
        public float[] Parameters
        {
            get { return _params; }
        }

        public void RecalculateInternalParameters()
        {
            filt = Math.Pow(10.0, -1.6 * _params[1]);
            gain = Math.Pow(10.0, 2.0 * _params[2] - 1.0);
            mix = _params[3];
        }

        public Dictionary<string, float[]> RegisterPresets()
        {
            Dictionary<string, float[]> presets = new Dictionary<string, float[]>();
            presets.Add("Soft Overdrive", new float[] { 0.0f, 0.0f, 0.5f });
            return presets;
        }

        public void Process(double[] leftBuffer, double[] rightBuffer)
        {
            int sampleFrames = leftBuffer.Length;
            double a, b, c, d;
            double i = _params[0], g = gain, aa, bb;
            double f = filt, fa = filt1, fb = filt2;
            double mixm = 1.0 - mix;

            for(int idx =0;idx<sampleFrames;idx++)
            {
                a = leftBuffer[idx];
                b = rightBuffer[idx];

                aa = (a > 0.0f) ? Math.Sqrt(a) : -Math.Sqrt(-a); //overdrive
                bb = (b > 0.0f) ? Math.Sqrt(b) : -Math.Sqrt(-b);

                fa = fa + f * (i * (aa - a) + a - fa);                //filter 
                fb = fb + f * (i * (bb - b) + b - fb);

                c = fa * g;
                d = fb * g;

                leftBuffer[idx] = (a * mixm) + (c * mix);
                rightBuffer[idx] = (b * mixm) + (d * mix);
            }
            if (Math.Abs(fa) > 1.0e-10) filt1 = fa; else filt1 = 0.0; //catch denormals
            if (Math.Abs(fb) > 1.0e-10) filt2 = fb; else filt2 = 0.0;
        }
    }
}
